package async_op

import "sync"

const maxWorkerCount = 2048
const workerTaskQSize = 1024

// 工人数组
var workerArray = [maxWorkerCount]*worker{}

// 初始化工人用的锁
var initWorkerLocker = &sync.Mutex{}

//
// Process 处理异步操作
// bindId = 绑定线程 Id
// asyncOp = 异步操作函数
// continueWith = 继续执行过程, 将在主线程中调用
func Process(bindId int, asyncOp func(), continueWith func()) {
	if nil == asyncOp {
		return
	}

	currWorker := getCurrWorker(bindId)

	if nil != currWorker {
		currWorker.process(asyncOp, continueWith)
	}
}

//
// 根据绑定 Id 获取当前工人
// bindId = 绑定线程 Id, 将和 len(workerArray) 做取余运算
func getCurrWorker(bindId int) *worker {
	if bindId < 0 {
		bindId = -bindId
	}

	workerIndex := bindId % len(workerArray)
	currWorker := workerArray[workerIndex]

	if nil != currWorker {
		return currWorker
	}

	// 加锁
	initWorkerLocker.Lock()
	defer initWorkerLocker.Unlock()

	// 获取当前工人
	currWorker = workerArray[workerIndex]

	// 二次判断
	if nil != currWorker {
		return currWorker
	}

	// 创建一个新的工人
	currWorker = &worker{
		taskQ: make(chan func(), workerTaskQSize),
	}

	// 循环执行任务
	go currWorker.loopExecTask()
	// 保存到工人数组
	workerArray[workerIndex] = currWorker

	return currWorker
}
